﻿using ArtMath.Attribute;
using ArtMath.Component.Point;
using ArtMath.Converter;
using ArtMath.Core.Data;
using ArtMath.Data;
using ArtMath.Resource;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using ArtMath.CommonType;

namespace ArtMath.Component.Line
{
    /// <summary>
    /// 垂线
    /// </summary>
    [Serializable]
    public class VerticalLine : PointSlopeLineBase
    {
        StraightLineBase line;
        PropertyDisplayer fpDisplayer;
        public VerticalLine(SketchPad pad, string name, StraightLineBase line, bool addToList = true) : base(pad, name, ToolTypeName.cx, addToList)
        {
            InPoints = new PointBase[1];
            StraightLine = line;
            FootPointDisplayer = new PropertyDisplayer(this, "FootPoint") { OffSet = AnchorOffset };
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("StraightLine"), TypeConverter(typeof(ExpandableObjectConverter))]
        public StraightLineBase StraightLine
        {
            get { return line; }
            set
            {
                line?.OutChildren_Line.Remove(this);
                line = value;
                if (line != null)
                {
                    line.OutChildren_Line.Add(this);
                    Slope = -1 / line.Slope;
                }
            }
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("AnchorPoint")]
        public PointBase PositionPoint
        {
            get { return InPoints[0]; }
            set { SetPoint(0, value); }
        }
        [MultilingualCategory("Parameter"), MultilingualDisplayName("FootPoint"), TypeConverter(typeof(IntelliPointConverter))]
        public PointD FootPoint
        {
            get { return PositionPoint.ToPointD().GetProjectivePoint(StraightLine.Location, StraightLine.Slope); }
        }
        [Browsable(false)]
        public PointD PFootPoint
        {
            get { return Pad.XYToPxy(FootPoint); }
        }
        [MultilingualCategory(null, "Sketchpad", "Display"), MultilingualDisplayName(null, "FootPoint", "Displayer")]
        public PropertyDisplayer FootPointDisplayer
        {
            get { return fpDisplayer; }
            set { fpDisplayer = value; }
        }
        public override double NewSlope
        {
            get { return -1 / StraightLine.NewSlope; }
        }
        public override double NewPSlope
        {
            get { return Pad.GetVerticalLinePSlope(StraightLine.NewPSlope); }
        }
        [Browsable(false)]
        public override AngleStringX RotateAngle
        {
            get
            {
                return base.RotateAngle;
            }

            set
            {
                base.RotateAngle = value;
            }
        }
        [Browsable(false)]
        public override RPointS RotateCenter
        {
            get
            {
                return base.RotateCenter;
            }

            set
            {
                base.RotateCenter = value;
            }
        }
        public override PointD AnchorPoint(PropertyDisplayer disp)
        {
            if (disp == FootPointDisplayer)
            {
                return PFootPoint;
            }
            return base.AnchorPoint(disp);
        }
        public override void CreateComponents()
        {
            if (PositionPoint == null)
            {
                PositionPoint = Pad.CreatePoint(Resources.Translate("AnchorPoint"), SpareCoordinate_);
                SpareCoordinate_ = PositionPoint.Pxy;//不加此句公式将不能正常显示
                Pad.TrackObj = this;
                base.CreateComponents();
            }
        }
        public override void RefreshPropertyDisplayersText()
        {
            FootPointDisplayer.RefreshText();
            base.RefreshPropertyDisplayersText();
        }
        public override void RefreshPropertyDisplayersLocation()
        {
            FootPointDisplayer.RefreshLocation();
            base.RefreshPropertyDisplayersLocation();
        }
        public override void PaintProperties(Graphics gra)
        {
            if (ObjectState == ObjectState.Normal && Visible)
            {
                FootPointDisplayer.Paint(gra);
            }
            base.PaintProperties(gra);
        }
        public override PropertyDisplayer[] PropertyDisplayersCheckNearBy(PointD Plocation)
        {
            List<PropertyDisplayer> res = new List<PropertyDisplayer>(base.PropertyDisplayersCheckNearBy(Plocation));
            if (FootPointDisplayer.InRegion(Plocation))
            {
                res.Add(FootPointDisplayer);
            }
            return res.ToArray();
        }
    }
}
